package com.iflytek.uoamp.notify.wechat.main;


import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.iflytek.uoamp.common.notify.util.Configurator;
import com.iflytek.uoamp.common.notify.util.LogbackInstance;
import com.iflytek.uoamp.notify.wechat.util.AccessToken;
import com.iflytek.uoamp.notify.wechat.util.HttpUtils;
import com.iflytek.uoamp.notify.wechat.util.WeixinUtil;
import com.iflytek.uoamp.notify.wechat.vo.MsgInfo;
import com.iflytek.uoamp.notify.wechat.vo.TemplateData;
import com.iflytek.uoamp.notify.wechat.vo.TokenVo;

import com.iflytek.uoamp.notify.wechat.vo.WxTemplate;

public class SendMsg {
	
	//private static Logger log = Logger.getLogger(SendMsg.class);
	
	private static Logger logger = LogbackInstance.getInstance().getLogger(SendMsg.class);
	
	public static final String GET_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token";// 获取access

	/**
	 * 发送模板消息 appId 公众账号的唯一标识 appSecret 公众账号的密钥 openId 用户标识
	 * 
	 * @param openId
	 * @param msgInfo
	 * @throws ExecutionException 
	 * @throws InterruptedException 
	 */
	public static void send_template_message(String openId, MsgInfo msgInfo) throws InterruptedException, ExecutionException {
		
		String appId = Configurator.getInstance().getPropertyByKey("weixin.appId", "");
		String appSecret = Configurator.getInstance().getPropertyByKey("weixin.appSecret", "");
		String templeteId = Configurator.getInstance().getPropertyByKey("weixin.templeteId", "");
		String fontColor = Configurator.getInstance().getPropertyByKey("weixin.fontcolor", "");
		
		AccessToken token = getAccessToken(appId, appSecret);
		String access_token = token.getToken();
		String url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + access_token;
		
		WxTemplate temp = new WxTemplate();
		temp.setTouser(openId);
		temp.setTopcolor(fontColor);
		temp.setTemplate_id(templeteId);
		
		Map<String, TemplateData> m = new HashMap<String, TemplateData>();
		TemplateData title = new TemplateData();
		title.setColor(fontColor);
		title.setValue(msgInfo.getTitle());
		m.put("first", title);
		TemplateData content = new TemplateData();
		content.setColor(fontColor);
		content.setValue(msgInfo.getContent());
		m.put("content", content);
		TemplateData time = new TemplateData();
		time.setColor(fontColor);
		time.setValue(msgInfo.getTime());
		m.put("time", time);
		temp.setData(m);
		
		String jsonString = JSONObject.toJSONString(temp);
		JSONObject jsonObject = WeixinUtil.httpRequest(url, "POST", jsonString);
		logger.info(JSON.toJSONString(jsonObject));
		int result = 0;
		if (null != jsonObject) {
			if (0 != jsonObject.getIntValue("errcode")) {
				result = jsonObject.getIntValue("errcode");
				logger.error("错误 errcode:{" + jsonObject.getString("errcode") + "} errmsg:{" + jsonObject.getString("errmsg") + "}");
			}
		}
		logger.info("模板消息发送结果：" + result);
	}

	/**
	 * 从文件中获取Acctoken,如果文件中时间和当前时间比较，超过7000s，则重新生成token，否则从文件中读取，
	 * 因为接口调用方法限制为每天200次
	 * 
	 * @param appId
	 * @param appSecret
	 * @return
	 * @throws ExecutionException 
	 * @throws InterruptedException 
	 */
	public static AccessToken getAccessToken(String appId, String appSecret) throws InterruptedException, ExecutionException {
		AccessToken token = null;
		// 查询数据库是否存在access_token
		List<TokenVo> list = getTokenListFromServer(appId);
		if(list != null && list.size() >0){
			long _time = Long.parseLong(String.valueOf(list.get(0).getCreateTime()));
			if((System.currentTimeMillis() - _time) /1000 < SysCode.EXPIRES_IN){//有效,直接从数据库中获取
				token = new AccessToken();
				token.setToken(String.valueOf(list.get(0).getAccessToken()));
				logger.info("=========从数据库中获取token值为："+token.getToken());
			} else{
				token = WeixinUtil.getAccessToken(appId, appSecret);
				updateTokenFromServer(token.getToken(),appId);
				logger.info("========更新数据库的token值为" + token.getToken());
			}
		}else{
			token = WeixinUtil.getAccessToken(appId, appSecret);
			insertTokenFromServer(token.getToken(),appId);
			logger.info("========第一次插入到数据库的 token值为" + token.getToken());
		}
		
		return token;
	}
	
	/**
	 * 
	 * @Title: insertTokenFromServer
	 * 插入token
	 * @param token
	 * @param appId   void
	 * @date 2017-4-7 上午8:35:33
	 * @throws
	 */
	private static void insertTokenFromServer(String accessToken,String appId){
		Map<String, Object> paraMap = new HashMap<String, Object>();
		paraMap.put("appId", appId);
		paraMap.put("accessToken", accessToken);
		paraMap.put("method", "insert");
		HttpUtils.doPost(Configurator.getInstance().getPropertyByKey("server_token_url", ""), JSON.toJSONString(paraMap));
	}
	
	
	/**
	 * 
	 * @Title: updateTokenFromServer
	 * 更新token
	 * @param token
	 * @param appId   void
	 * @date 2017-4-6 下午5:39:28
	 * @throws
	 */
	private static void updateTokenFromServer(String accessToken,String appId){
		Map<String, Object> paraMap = new HashMap<String, Object>();
		paraMap.put("appId", appId);
		paraMap.put("accessToken", accessToken);
		paraMap.put("method", "update");
		HttpUtils.doPost(Configurator.getInstance().getPropertyByKey("server_token_url", ""), JSON.toJSONString(paraMap));
	}
	
	
	/**
	 * 
	 * @Title: getTokenList
	 * 获取数据库中token集合
	 * @param appId
	 * @return
	 * @throws InterruptedException
	 * @throws ExecutionException   List<TokenVo>
	 * @date 2017-4-6 下午5:20:56
	 * @throws
	 */
	private static List<TokenVo> getTokenListFromServer(String appId) {
		List<TokenVo> list = new ArrayList<TokenVo>();
		Map<String, Object> paraMap = new HashMap<String, Object>();
		paraMap.put("appId", appId);
		paraMap.put("method", "select");
		//线程池执行
		String result = HttpUtils.doPost(Configurator.getInstance().getPropertyByKey("server_token_url", ""), JSON.toJSONString(paraMap));
		logger.info("get token from server ========================"+"result:"+result);
		if(StringUtils.isNotEmpty(result)){
			list = new Gson().fromJson(result,  new TypeToken<List<TokenVo>>() {  }.getType());
		}
		return list;
	}
}
